﻿using SpotsHub.RouteService.Data;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SpotsHub.RouteService.Strategy
{
    class SameLocalityStrategy : StrategyBase
    {
        public override void Caculate()
        {
            // TODO: Fix pickup and drop in different cities.
            var wps = new List<Location>(Plan.UnresolvedWaypoints);
            var gourpedWps = new Dictionary<int, List<Location>>();

            foreach (var wp in wps)
	        {
                if (!gourpedWps.ContainsKey(wp.Address.City.Id))
                {
                    gourpedWps.Add(wp.Address.City.Id, new List<Location>());
                }
                gourpedWps[wp.Address.City.Id].Add(wp);
	        }

            var das = new List<DriverAssignment>(Plan.DriverAssignments);

            var cs = (int[])gourpedWps.Keys.ToArray().Clone();
            foreach (var c in cs)
            {
                var d = ChooseDriver(c, das);

                if (d != null)
                {
                    d.UnresolvedWaypoints = gourpedWps[c].ToArray();
                    gourpedWps.Remove(c);
                    das.Remove(d);
                }
            }

            if (gourpedWps.Count > 0)
            {
                cs = (int[])gourpedWps.Keys.ToArray().Clone();
                foreach (var c in cs)
                {
                    if (das.Count <= 0)
                    {
                        break;
                    }
                    var d = das[0].UnresolvedWaypoints = gourpedWps[c].ToArray();
                    gourpedWps.Remove(c);
                    das.RemoveAt(0);
                }
            }

            var unresolved = new List<Location> ();
            foreach (var v in gourpedWps.Values)
            {
                unresolved.AddRange(v);
            }
            Plan.UnresolvedWaypoints = unresolved.ToArray();
        }

        public override int Priorty
        {
            get { return 10; }
        }

        private DriverAssignment ChooseDriver(int c, List<DriverAssignment> das)
        {
            var ds = from d in das
                     where (d.Driver.PreferredLocalities != null && d.Driver.IsPreferredLocality(c))
                     select d;
            if (ds.Count() > 0)
            {
                return ds.FirstOrDefault();
            }

            ds = from d in das
                     where d.Driver.PreferredLocalities == null
                     select d;
            if (ds.Count() > 0)
            {
                return ds.FirstOrDefault();
            }

            return null;
        }
    }
}
